//
//  AudioRecorderView.m
//  EcmCustomer
//
//  Created by 张进 on 15/8/3.
//  Copyright (c) 2015年 张进. All rights reserved.
//

#import "AudioRecorderView.h"
#import <AVFoundation/AVFoundation.h>
#import "AudioHelper.h"

/*
 *  播放状态
 */
enum PlayingState{
    PlayingState_isPlaying = 1,
    PlayingState_isPausing = 2,
    PlayingState_isStoped = 0
};

@interface AudioRecorderView()<AVAudioRecorderDelegate,AVAudioPlayerDelegate>{
//    NSDate *startDate;
//    NSTimeInterval recordInterval;
    CGPoint touchDownPoint;

    AudioHelper *audioHelper;
    
    NSURL *recordedFile;
    AVAudioPlayer *player;
    AVAudioRecorder *recorder;
    NSTimer *detectionVoiceTimer;
    
    enum PlayingState playState;
    BOOL canRecord;
    BOOL canCancelRecord;
}


@end

@implementation AudioRecorderView

//@synthesize recorder,urlPlay;
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/



+(AudioRecorderView *)instanceWithFrame:(CGRect)rect existRecordButton:(UIButton *)recordButton existPlayButton:(UIButton *)playButton{
    NSArray* nibView =  [[NSBundle mainBundle] loadNibNamed:@"AudioRecorderView" owner:nil options:nil];
    
    AudioRecorderView *item = [nibView lastObject];
    item.frame = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
    item.imageView.contentMode=UIViewContentModeScaleAspectFill;
    item.imageView.clipsToBounds=YES;
    
    [item initWithRecordButton:recordButton playButton:playButton];
    
    return item;
}
#pragma mark - 初始化
-(void)initWithRecordButton:(UIButton *)recordButton playButton:(UIButton *)playButton{
    self.hidden = YES;
    
    if (recordButton == nil) {
        return;
    }
    //初始化音频设置
    [self initAudioSetting];
    
    if (recordButton == playButton) {
        [recordButton addTarget:self action:@selector(startRecord:withEvent:) forControlEvents:UIControlEventTouchDown];
        [recordButton addTarget:self action:@selector(endRecordOrStartPlay:) forControlEvents:UIControlEventTouchUpInside];
        [recordButton addTarget:self action:@selector(endRecordOrStartPlay:) forControlEvents:UIControlEventTouchUpOutside];
        [playButton addTarget:self action:@selector(endRecordOrStartPlay:) forControlEvents:UIControlEventTouchUpInside];
        
        //录音按钮上划取消录音
        [recordButton addTarget:self action:@selector(swapeUpToCancel:withEvent:) forControlEvents:UIControlEventTouchDragInside];
        
    }else{
        [recordButton addTarget:self action:@selector(voiceButtonTouchDown:withEvent:) forControlEvents:UIControlEventTouchDown];
        [recordButton addTarget:self action:@selector(voiceButtonTouchUp:) forControlEvents:UIControlEventTouchUpInside];
        [recordButton addTarget:self action:@selector(voiceButtonTouchUp:) forControlEvents:UIControlEventTouchUpOutside];
        //录音按钮上划取消录音
        [recordButton addTarget:self action:@selector(swapeUpToCancel:withEvent:) forControlEvents:UIControlEventTouchDragInside];
        
        if (playButton != nil) {
            [playButton addTarget:self action:@selector(playButtonTouchUpInside:) forControlEvents:UIControlEventTouchUpInside];
        }
    }
    
    
}
//初始化音频设置
- (void)initAudioSetting
{
    //录音设置
    //录音设置
    NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc]init];
    //设置录音格式  AVFormatIDKey==kAudioFormatLinearPCM
    [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
    //设置录音采样率(Hz) 如：AVSampleRateKey==8000/44100/96000（影响音频的质量）
    [recordSetting setValue:[NSNumber numberWithFloat:44100] forKey:AVSampleRateKey];
    //录音通道数  1 或 2
    [recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
    //线性采样位数  8、16、24、32
    [recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    //录音的质量
    [recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
    
    NSString *strUrl = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    recordedFile = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/luyin.aac", strUrl]];
    
    
    AVAudioSession *session = [AVAudioSession sharedInstance];
    
    NSError *sessionError;
    [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
    
    if(session == nil)
        NSLog(@"Error creating session: %@", [sessionError description]);
    else
        [session setActive:YES error:nil];
    
    audioHelper = [[AudioHelper alloc] init];
    [audioHelper initSession];
    
    recorder = [[AVAudioRecorder alloc] initWithURL:recordedFile settings:recordSetting error:nil];//开启音量检测
    recorder.meteringEnabled = YES;
    recorder.delegate = self;
    canRecord = YES;
    canCancelRecord = NO;
    
    playState = PlayingState_isStoped;
}

#pragma mark - 录音按钮与播放按钮为两个按钮-两个按钮可覆盖录音
//按下录音
-(void)voiceButtonTouchDown:(UIControl *)control withEvent:(id)event{
    
    touchDownPoint = [[[event allTouches] anyObject] locationInView:self];
    
    //录音开始
    [self startRecording];
    
}

//抬起结束或取消录音
-(void)voiceButtonTouchUp:(UIControl *)control{
    self.hidden = YES;
    self.descLabel.text = @"手指上划可取消录音";
    
    //结束或取消录音
    [self finishOrCancelRecording];
    //允许覆盖录音
    canRecord = YES;
}

//播放
-(void)playButtonTouchUpInside:(UIControl *)control{
    //播放录音
    [self playRecording];
}
#pragma mark - 录音按钮与播放按钮为同一个按钮
//按下录音
-(void)startRecord:(UIControl *)control withEvent:(id)event{
    if (canRecord) {
        touchDownPoint = [[[event allTouches] anyObject] locationInView:self];
        //录音开始
        [self startRecording];
    }
    
}
//抬起结束或取消或播放录音
-(void)endRecordOrStartPlay:(UIControl *)control{
    if (canRecord) {
        
        self.hidden = YES;
        self.descLabel.text = @"手指上划可取消录音";
        
        //结束或取消录音
        [self finishOrCancelRecording];
        
    }else{
        //播放录音
        [self playRecording];
    }
    
}
//上划取消录音
-(void)swapeUpToCancel:(UIControl *)control withEvent:(id)event{
    if (canRecord) {
        CGPoint point = [[[event allTouches] anyObject] locationInView:self];
        CGFloat deltaY = touchDownPoint.y - point.y;
        if (deltaY > 30) {
            if (!canCancelRecord) {
                //取消音量检测
                if (detectionVoiceTimer) {
                    [detectionVoiceTimer invalidate];
                }
                
                self.descLabel.text = @"手指松开可取消录音";
                canCancelRecord = YES;
                self.imageView.image = [UIImage imageNamed:@"record_cancel"];
            }
        }else{
            if (canCancelRecord) {
                self.descLabel.text = @"手指上划可取消录音";
                canCancelRecord = NO;
                
                //设置定时检测音量重新设置音量检测
                if (detectionVoiceTimer) {
                    [detectionVoiceTimer invalidate];
                }
                [self setDetectionVoiceOn];
                
            }
        }
    }
}

//开始录音
-(void)startRecording{
    //录音开始
    [audioHelper checkAndPrepareCategoryForRecording];
    if ([recorder prepareToRecord]) {
        self.hidden = NO;
        [recorder record];
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(recorderDidStartRecording)]) {
            [self.delegate recorderDidStartRecording];
        }
        //设置定时检测音量
        [self setDetectionVoiceOn];
    }
}
//结束或取消录音
-(void)finishOrCancelRecording{
    
    //取消录音
    if (canCancelRecord) {
        //销毁音量定时检测
        if (detectionVoiceTimer) {
            [detectionVoiceTimer invalidate];
        }
        [recorder stop];
        [recorder deleteRecording];
        
        [audioHelper cleanUpForEndRecording];
        if (self.delegate && [self.delegate respondsToSelector:@selector(recorderDidCancelRecording)]) {
            [self.delegate recorderDidCancelRecording];
        }
        
        canCancelRecord = NO;
        canRecord = YES;
    }else{
        //录音结束
        
        //销毁音量定时检测
        if (detectionVoiceTimer) {
            [detectionVoiceTimer invalidate];
        }
        [recorder stop];
        
        [audioHelper cleanUpForEndRecording];
        
        canRecord = NO;
    }
}
//播放录音
-(void)playRecording{
    if (playState == PlayingState_isPlaying) {
        [player pause];
        playState = PlayingState_isPausing;
        if (self.delegate && [self.delegate respondsToSelector:@selector(playerDidPausePlaying)]) {
            [self.delegate playerDidPausePlaying];
        }
    }else if (playState == PlayingState_isPausing) {
        [player play];
        playState = PlayingState_isPlaying;
        if (self.delegate && [self.delegate respondsToSelector:@selector(playerDidContinuePlaying)]) {
            [self.delegate playerDidContinuePlaying];
        }
    }else if (playState == PlayingState_isStoped){
        player = nil;
        NSError *playerError;
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedFile error:&playerError];
        player.delegate = self;
        [player play];
        playState = PlayingState_isPlaying;
        if (self.delegate && [self.delegate respondsToSelector:@selector(playerDidStartPlaying)]) {
            [self.delegate playerDidStartPlaying];
        }
    }
}

#pragma mark - 声音定时检测
-(void)setDetectionVoiceOn{
    //设置定时检测
    detectionVoiceTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(detectionVoice) userInfo:nil repeats:YES];
}
- (void)detectionVoice
{
    [recorder updateMeters];//刷新音量数据
    //获取音量的平均值  [recorder averagePowerForChannel:0];
    //音量的最大值  [recorder peakPowerForChannel:0];
//    NSLog(@"peakPowerForChannel:%f",[recorder peakPowerForChannel:0]);
    
    double lowPassResults = pow(10, (0.05 * [recorder peakPowerForChannel:0]));
//    NSLog(@"%lf",lowPassResults);
    //最大50  0
    //图片 小-》大
    if (0<lowPassResults<=0.06) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_01.png"]];
    }else if (0.06<lowPassResults<=0.13) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_02.png"]];
    }else if (0.13<lowPassResults<=0.20) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_03.png"]];
    }else if (0.20<lowPassResults<=0.27) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_04.png"]];
    }else if (0.27<lowPassResults<=0.34) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_05.png"]];
    }else if (0.34<lowPassResults<=0.41) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_06.png"]];
    }else if (0.41<lowPassResults<=0.48) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_07.png"]];
    }else if (0.48<lowPassResults<=0.55) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_08.png"]];
    }else if (0.55<lowPassResults<=0.62) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_09.png"]];
    }else if (0.62<lowPassResults<=0.69) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_10.png"]];
    }else if (0.69<lowPassResults<=0.76) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_11.png"]];
    }else if (0.76<lowPassResults<=0.83) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_12.png"]];
    }else if (0.83<lowPassResults<=0.9) {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_13.png"]];
    }else {
        [self.imageView setImage:[UIImage imageNamed:@"record_animate_14.png"]];
    }
}

#pragma mark - 删除录音
/**
 *  删除录音
 */
-(void)deleteRecord{
    if (!canRecord) {
        if (recorder.isRecording) {
            [recorder stop];
        }
        [recorder deleteRecording];
        canRecord = YES;
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(recordingHasDeleted)]) {
            [self.delegate recordingHasDeleted];
        }
        
        if (player) {
            [player stop];
            playState = PlayingState_isStoped;
        }
        
    }
}

#pragma mark - 暂停播放录音
/*
 *  暂停播放录音
 */
-(void)playerPause{
    if (player && player.isPlaying) {
        [player pause];
    }
}
#pragma mark - AVAudioRecorderDelegate
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
    AVURLAsset* audioAsset =[AVURLAsset URLAssetWithURL:recordedFile options:nil];
    CMTime audioDuration = audioAsset.duration;
    float audioDurationSeconds =CMTimeGetSeconds(audioDuration);
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(recorderDidFinishRecording:)]) {
        [self.delegate recorderDidFinishRecording:audioDurationSeconds];
    }
    
}

/* if an error occurs while encoding it will be reported to the delegate. */
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)_recorder error:(NSError *)error{
    [recorder stop];
    [recorder deleteRecording];
    canRecord = YES;
    if (self.delegate && [self.delegate respondsToSelector:@selector(recorderEncodeErrorDidOccur:)]) {
        [self.delegate recorderEncodeErrorDidOccur:error];
    }
}
#pragma mark - AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    playState = PlayingState_isStoped;
    if (self.delegate && [self.delegate respondsToSelector:@selector(playerDidFinishPlaying)]) {
        [self.delegate playerDidFinishPlaying];
    }
}

/* if an error occurs while decoding it will be reported to the delegate. */
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
    playState = PlayingState_isStoped;
    if (self.delegate && [self.delegate respondsToSelector:@selector(playerDecodeErrorDidOccur:)]) {
        [self.delegate playerDecodeErrorDidOccur:error];
    }
}

@end
